package org.hackystat.linkedservicedata.ui;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hackystat.linkedservicedata.ui.issues.IssuesPanel;
import org.hackystat.linkedservicedata.ui.network.NetworkPanel;
import org.hackystat.linkedservicedata.ui.projects.ProjectsPanel;
import org.hackystat.linkedservicedata.ui.users.UsersPanel;
import org.hackystat.linkedservicedata.vocabularies.HackystatConstants;

/**
 * Main window containing all the other panels into tabs.
 *
 * @author Myriam Leggieri.
 *
 */
public class Start extends LinkedServiceDataUI {

  /** Auto-generated serial version id. */
  private static final long serialVersionUID = 4268685212560864275L;

  /** Icon of the Hackystat logo. */
  private static ImageIcon icon = createImageIcon("img/hackystat.gif");

  /** Icon label. */
  private JLabel iconLabel = null;

  /** Layered panel. */
  private JLayeredPane layeredPane = null;

  /** Main container */
  private Container container = null;

  /** Combo box to allow choosing the RDF serialization language. */
  private JComboBox languageCombo = null;

  /** RDF serialization language label */
  private JLabel languageLabel = null;

  /** Panel to contains tabs */
  private JTabbedPane tabbedPane = null;

  /** SignIn Panel Component */
  private JComponent signInPanelComponent = null;

  /** Users Panel Component */
  private JComponent usersPanelComponent = null;

  /** Issues Panel Component */
  private JComponent issuesPanelComponent = null;

  /** Network Panel Component */
  private JComponent networkPanelComponent = null;

  /** Projects Panel Component */
  private JComponent projectsPanelComponent = null;

  /** Users Icon */
  private ImageIcon usersIcon = null;

  /** Issues Icon */
  private ImageIcon issuesIcon = null;

  /** Projects Icon */
  private ImageIcon projectsIcon = null;

  /** Network Icon */
  private ImageIcon networkIcon = null;

  /** SignIn Icon */
  private ImageIcon signInIcon = null;

  /** SignIn Panel */
  private SignInPanel signInPanel = null;

  /** Users Panel */
  private UsersPanel usersPanel = null;

  /** Issues Panel */
  private IssuesPanel issuesPanel = null;

  /** Projects Panel */
  private ProjectsPanel projectsPanel = null;

  /** Network Panel */
  private NetworkPanel networkPanel = null;

  /** Currently selected RDF serialization language. */
  private Object selectedLanguage = null;

  /** Check if the log-in status of a user has changed and then the tab content should be reset. */
  public static boolean refreshAllTabs = false;

  public Start() {
    super();
    initComponents(false);
    setBackground(Color.white);
    super.setSerializationLanguage(String.valueOf(languageCombo.getSelectedItem()));
  }

  private void createIcons() {
    usersIcon = createImageIcon("img/users.gif");
    issuesIcon = createImageIcon("img/issues.gif");
    projectsIcon = createImageIcon("img/projects.gif");
    signInIcon = createImageIcon("img/signin.gif");
    networkIcon = createImageIcon("img/network.gif");
  }

  @Override
  protected void initComponents(boolean refreshAllTabs) {
    Start.refreshAllTabs = refreshAllTabs;
    createIcons();
    container = getContentPane();
    container.removeAll();
    container.setBackground(Color.WHITE);
    container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));

    layeredPane = new JLayeredPane();
    iconLabel = new JLabel("LinkedServiceData Browser", icon, JLabel.RIGHT);
    // Set the position of the text, relative to the icon:
    iconLabel.setVerticalTextPosition(JLabel.CENTER);
    iconLabel.setHorizontalTextPosition(JLabel.RIGHT);
    iconLabel.setVerticalAlignment(JLabel.TOP);
    iconLabel.setHorizontalAlignment(JLabel.LEFT);
    iconLabel.setOpaque(true);
    iconLabel.setForeground(Color.BLUE);
    iconLabel.setBounds(0, 0, icon.getIconWidth() + 500, icon.getIconHeight());
    iconLabel.setFont(new Font("Dialog", java.awt.Font.BOLD, 20));
    iconLabel.setBackground(Color.white);

    layeredPane.add(iconLabel, new Integer(0));
    layeredPane.setBackground(Color.white);

    Point origin = null;
    if (languageLabel == null) {
      languageLabel = new JLabel();
      languageLabel.setText("RDF Serialization Language:");
      languageLabel.setDisplayedMnemonic(KeyEvent.VK_U);
      languageLabel.setForeground(Color.BLUE);
      origin = new Point(1200, 20);
      languageLabel.setBounds(origin.x, origin.y, 300, 30);
      languageLabel.setFont(new Font("Dialog", java.awt.Font.PLAIN, 18));
    }
    layeredPane.add(languageLabel);
    if (languageCombo == null) {
      String[] langs = new String[] { HackystatConstants.LANG_N3, HackystatConstants.LANG_NTRIPLE,
          HackystatConstants.LANG_RDFXML, HackystatConstants.LANG_RDFXML_ABBREV,
          HackystatConstants.LANG_TURTLE };
      origin = new Point(1450, 25);
      languageCombo = new JComboBox(langs);
      languageCombo.setBounds(origin.x, origin.y, 150, 20);
      languageCombo.addItemListener(this);
    }
    layeredPane.add(languageCombo);

    container.add(layeredPane);

    tabbedPane = new JTabbedPane();
    tabbedPane.setFont(new Font("Dialog", Font.PLAIN, 13));
    tabbedPane.setBackground(Color.white);
    selectedTabIndex = tabbedPane.getSelectedIndex();
    // Register a change listener
    tabbedPane.addChangeListener(new ChangeListener() {
      // This method is called whenever the selected tab changes
      public void stateChanged(ChangeEvent evt) {
        JTabbedPane pane = (JTabbedPane) evt.getSource();
        // Get current tab
        selectedTabIndex = pane.getSelectedIndex();
        switch (selectedTabIndex) {
        case 1:
          if (Start.refreshAllTabs) {
            usersPanel.resetPanel();
          }else{
            usersPanel.prepareDisplaying();
          }
          break;
        case 2:
          if (Start.refreshAllTabs) {
            projectsPanel.resetPanel();
          }
          else {
            projectsPanel.prepareDisplaying();
          }
          break;
        case 3:
          if (Start.refreshAllTabs) {
            issuesPanel.resetPanel();
          }
          else {
            issuesPanel.prepareDisplaying();
          }
          break;
        case 4:
          networkPanel.prepareDisplaying();
          break;
        }
      }
    });

    if (signInPanel == null) {
      signInPanelComponent = makeSignInPanel();
    }else{
      signInPanel.repaint();
    }

    tabbedPane.addTab("Authentication", signInIcon, signInPanelComponent,
        "Hackystat authentication");
    tabbedPane.setMnemonicAt(0, KeyEvent.VK_S);

    if (usersPanel == null) {
      usersPanelComponent = makeUsersPanel();
    }else{
      usersPanel.repaint();
    }

    tabbedPane.addTab("Users", usersIcon, usersPanelComponent,
        "View, search and edit registered users.");
    tabbedPane.setMnemonicAt(1, KeyEvent.VK_U);

    if (projectsPanel == null) {
      projectsPanelComponent = makeProjectsPanel();
    }else{
      projectsPanel.repaint();
    }

    tabbedPane.addTab("Projects", projectsIcon, projectsPanelComponent,
        "View, search and edit stored projects.");
    tabbedPane.setMnemonicAt(2, KeyEvent.VK_P);

    if (issuesPanel == null) {
      issuesPanelComponent = makeIssuesPanel();
    }else{
      issuesPanel.repaint();
    }

    tabbedPane.addTab("Issues", issuesIcon, issuesPanelComponent,
        "View, search and edit stored issues");
    tabbedPane.setMnemonicAt(3, KeyEvent.VK_I);

    if (networkPanel == null) {
      networkPanelComponent = makeNetworkPanel();
    }else{
      networkPanel.repaint();
    }
    tabbedPane.addTab("Network", networkIcon, networkPanelComponent,
        "View, add and delete the list of servers included in your " + "Hackystat network");
    tabbedPane.setMnemonicAt(3, KeyEvent.VK_N);

    container.add(Box.createVerticalStrut(10));
    container.add(tabbedPane);
    container.validate();
    setTitle("Hackystat - LinkedServiceData Browser");
    setLocationRelativeTo(null);
    setBackground(Color.white);
    this.setVisible(true);
  }

  protected void processWindowEvent(WindowEvent e) {
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      if (confirmExit() == 0) {
        System.exit(0);
      }
    }
  }

  private int confirmExit() {
    int choice = JOptionPane.showConfirmDialog(this, "Are you sure you want to exit program?",
        "Hackystat - Verification required", JOptionPane.OK_CANCEL_OPTION);
    return choice;
  }

  public static void main(String[] args) {
    Start obj = new Start();
    JFrame applicationWindow = obj;
    applicationWindow.pack();
    applicationWindow.setSize(obj.winDimension);
    applicationWindow.setLocationRelativeTo(null);
    applicationWindow.setVisible(true);
    applicationWindow.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    applicationWindow.setBackground(Color.white);
  }

  private JComponent makeProjectsPanel() {

    JPanel pannelloMain, pannello;

    pannello = new JPanel();
    pannello.setLayout(new BoxLayout(pannello, BoxLayout.Y_AXIS));
    pannello.add(Box.createVerticalStrut(8));

    pannelloMain = new JPanel();

    pannelloMain.setLayout(new BoxLayout(pannelloMain, BoxLayout.X_AXIS));
    Border loweredetched = BorderFactory.createLineBorder(Color.blue);
    projectsPanel = new ProjectsPanel(this);
    pannelloMain.add(projectsPanel);

    TitledBorder title = BorderFactory.createTitledBorder(loweredetched, "Projects", 0, 0,
        new Font("Dialog", Font.BOLD, 13), Color.BLUE);
    pannelloMain.setBorder(title);

    pannelloMain.setBackground(Color.white);
    pannello.add(pannelloMain);
    pannello.setBackground(Color.white);
    return pannello;

  }

  private JComponent makeSignInPanel() {

    JPanel pannelloMain, pannello;

    pannello = new JPanel();
    pannello.setLayout(new BoxLayout(pannello, BoxLayout.Y_AXIS));
    pannello.add(Box.createVerticalStrut(8));

    pannelloMain = new JPanel();

    pannelloMain.setLayout(new BoxLayout(pannelloMain, BoxLayout.X_AXIS));
    Border loweredetched = BorderFactory.createLineBorder(Color.blue);
    signInPanel = new SignInPanel(this);
    pannelloMain.add(signInPanel);

    TitledBorder title = BorderFactory.createTitledBorder(loweredetched, "Authentication", 0, 0,
        new Font("Dialog", Font.BOLD, 13), Color.BLUE);
    pannelloMain.setBorder(title);

    pannelloMain.setBackground(Color.white);
    pannello.add(pannelloMain);
    pannello.setBackground(Color.white);

    return pannello;

  }

  private JComponent makeUsersPanel() {
    JPanel pannelloMain, pannello;

    pannello = new JPanel();
    pannello.setLayout(new BoxLayout(pannello, BoxLayout.Y_AXIS));
    pannello.add(Box.createVerticalStrut(8));

    pannelloMain = new JPanel();

    pannelloMain.setLayout(new BoxLayout(pannelloMain, BoxLayout.X_AXIS));
    Border loweredetched = BorderFactory.createLineBorder(Color.blue);
    usersPanel = new UsersPanel(this);
    pannelloMain.add(usersPanel);

    TitledBorder title = BorderFactory.createTitledBorder(loweredetched, "Users", 0, 0, new Font(
        "Dialog", Font.BOLD, 13), Color.BLUE);
    pannelloMain.setBorder(title);

    pannelloMain.setBackground(Color.white);
    pannello.add(pannelloMain);
    pannello.setBackground(Color.white);
    return pannello;

  }

  private JComponent makeNetworkPanel() {
    JPanel pannelloMain, pannello;

    pannello = new JPanel();
    pannello.setLayout(new BoxLayout(pannello, BoxLayout.Y_AXIS));
    pannello.add(Box.createVerticalStrut(8));

    pannelloMain = new JPanel();

    pannelloMain.setLayout(new BoxLayout(pannelloMain, BoxLayout.X_AXIS));
    networkPanel = new NetworkPanel(this);
    pannelloMain.add(networkPanel);

    Border loweredetched = BorderFactory.createLineBorder(Color.blue);
    TitledBorder title = BorderFactory.createTitledBorder(loweredetched, "Network", 0, 0, new Font(
        "Dialog", Font.BOLD, 13), Color.BLUE);
    pannelloMain.setBorder(title);

    pannelloMain.setBackground(Color.white);
    pannello.add(pannelloMain);
    pannello.setBackground(Color.white);

    return pannello;
  }

  private JComponent makeIssuesPanel() {
    JPanel pannelloMain, pannello;

    pannello = new JPanel();
    pannello.setLayout(new BoxLayout(pannello, BoxLayout.Y_AXIS));
    pannello.add(Box.createVerticalStrut(8));

    pannelloMain = new JPanel();

    pannelloMain.setLayout(new BoxLayout(pannelloMain, BoxLayout.X_AXIS));
    issuesPanel = new IssuesPanel(this);
    pannelloMain.add(issuesPanel);

    Border loweredetched = BorderFactory.createLineBorder(Color.blue);
    TitledBorder title = BorderFactory.createTitledBorder(loweredetched, "Issues", 0, 0, new Font(
        "Dialog", Font.BOLD, 13), Color.BLUE);
    pannelloMain.setBorder(title);

    pannelloMain.setBackground(Color.white);
    pannello.add(pannelloMain);
    pannello.setBackground(Color.white);

    return pannello;
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub

  }

  @Override
  public void itemStateChanged(ItemEvent e) {
    Object source = e.getSource();
    if (source.equals(languageCombo)) {
      super.setSerializationLanguage(String.valueOf(languageCombo.getSelectedItem()));
      if (selectedTabIndex != 0 && !languageCombo.getSelectedItem().equals(selectedLanguage)) {
        selectedLanguage = languageCombo.getSelectedItem();
        JOptionPane.showMessageDialog(this, "Language preference changes don't take "
            + "effect until tab refreshing.", "Hackystat - Warning Message",
            JOptionPane.WARNING_MESSAGE);
      }
    }
  }

}
